#include "stdafx.h"
#include "display.h"

void displayLoop( int step ) {
	CURR_STEP = step;

	if (SCREEN == MAIN || SCREEN == GAMEOVER) {
		// set current time
		CURR_TIME_MS = glutGet(GLUT_ELAPSED_TIME);
		int time = CURR_TIME_MS/1000;
		if (time > CURR_TIME) {
			CURR_TIME = time;
			if (SCREEN == MAIN)
				playSound("../../sounds/tick.wav");
		}
	}

	if (CURR_TIME == CLEAR_TEXTURE_TIME) {
		IS_TEXTURE_SHOWING = false;

		// free textures
		glDeleteTextures( 1, &TEXTURE );
	}

	if (SECONDS_PER_SHAPE - (CURR_TIME-PREV_TIME) <= -1) {
		showNewShape(false);
	}

	glMatrixMode( GL_MODELVIEW );                // Setup model transformations
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

	glPushMatrix();

	// adjust the position of shapes and sillhoutte
	glScalef(.8, .8, .8);
	glTranslatef(0, -.1f, 0);

	Shape *shape;
	// begin main area

	if (PREV_SHAPE) {
		int stepDiff = step - PREV_STEP;
		glPushMatrix();
		glTranslatef(0, 0, (float)stepDiff/5.f);
		displayShape(0, PREV_SHAPE);
		glPopMatrix();
	}

	if (MODE == PLAY && SCREEN == MAIN) {
		glPushMatrix();
		shape = shapes.at(ACTIVE_SHAPE);
		// if it's during a shape transition
		if (PREV_SHAPE) {
			int stepDiff = step - PREV_STEP - 50;
			float z = (float) stepDiff * stepDiff / -5.f;
			glTranslatef(0, 0, z);
			// stop transition when the new shape is at z=0 (or more)
			if (stepDiff > 0) {
				PREV_SHAPE = NULL;
			}
		}

		displayShape(step, shape);
		glPopMatrix();
	}

	if (SCREEN == MAIN) {
		glPushMatrix();
		displaySilhoutte(step);
		glPopMatrix();
	}
	
	// end main area

	glPopMatrix();

	glPushMatrix();
	displayScore(step, TOTAL_SCORE, CURR_TIME);
	glPopMatrix();

	glPushMatrix();
	displayBar(step);
	glPopMatrix();

	if (SCREEN == HELP) {
		glPushMatrix();
		displayHelp(step);
		displayScore(step, 3, 1);
		glPopMatrix();
	}

	if (MODE == CREATE && !outline.empty()) {
		glPushMatrix();
		shape = new Shape();
		shape->setOutline(outline);
		shape->setRequired(required);
		displayShape(step, shape);
		glPopMatrix();
	}	

	// At last, render bitmaps
	if (rasterTimer[DISPLAY_CLEAR] > CURR_TIME)
		renderPNG("../../gfx/clear.png",-0.7,0.);
	if (rasterTimer[DISPLAY_NOT_CLEAR] > CURR_TIME)
		renderPNG("../../gfx/not_clear.png",-0.7,0.0);
	
	if (rasterTimer[DISPLAY_NEXTLEVEL] > CURR_TIME)
		renderPNG("../../gfx/next_level.png",-0.7,-0.8);
	if (rasterTimer[DISPLAY_GAMEOVER] > CURR_TIME) {
		renderPNG("../../gfx/game_over.png",-0.7,-0.5);
	} else {
		if (SCREEN == GAMEOVER) {
			// restart game
			TOTAL_SCORE = 0;
			SCORE = 0;
			LIVES = 3;
			SCREEN = HELP;
		}
	}

	// But lifes up there
	for (int i = 0; i < LIVES; i++) {
		renderPNG("../../gfx/life.png",-1 + i*0.2,0.8);
	}

	/* clear the screen */
	glFlush();
	/* use double buffering to avoid flicker? */
	glutSwapBuffers();
	/* and repeat */
	glutTimerFunc( 1, displayLoop, ++step );
}

void displayWin( void ) {

	float  amb[] = { 0, 0, 0, 1 };        // Ambient material property
	float  lt_amb[] = { .2, .2, .2, 1 };        // Ambient light property
	float  lt_dif[] = { .8, .8, .8, 1 };        // Ambient light property
	float  lt_pos[] = { 0, .39392, .91914, 0 }; // Light position
	float  lt_spc[] = { 0, 0, 0, 1 };        // Specular light property

	//  Set default ambient light in scene
	glLightModelfv( GL_LIGHT_MODEL_AMBIENT, amb );

	//  Set Light 0 position, ambient, diffuse, specular intensities
	glLightfv( GL_LIGHT0, GL_POSITION, lt_pos );
	glLightfv( GL_LIGHT0, GL_AMBIENT, lt_amb );
	glLightfv( GL_LIGHT0, GL_DIFFUSE, lt_dif );
	glLightfv( GL_LIGHT0, GL_SPECULAR, lt_spc );

	glClear( GL_COLOR_BUFFER_BIT );
	glEnable( GL_CULL_FACE );
	glCullFace( GL_BACK );

	//  Enable Light 0 and GL lighting
	glEnable( GL_LIGHT0 );
	glEnable( GL_LIGHTING );

	glEnable( GL_DEPTH );

	glEnable( GL_POINT_SMOOTH );    // Anti-alias points

	glShadeModel( GL_FLAT );                // Flat shading
	glEnable( GL_NORMALIZE );                // Normalize normals

	glClearDepth( 1.0 );                        // Setup background colour
	glClearColor( 0, 0, 0, 0 );
}

void handleMenu( int i ) {
	/* handle menu selection */
	switch( i ) {
		case 10:
			exit( 1 );
			break;
	}
}

void reshapeWin( int w, int h ) {

	glViewport( 0, 0, w, h );

	glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
	glLoadIdentity();							// Reset The Projection Matrix

	// Calculate The Aspect Ratio Of The Window
	gluPerspective(45.0f,(GLfloat)WINDOW_WIDTH/(GLfloat)WINDOW_HEIGHT,0.1f,100.0f);

	glMatrixMode(GL_MODELVIEW);						// Select The Modelview Matrix
	glLoadIdentity();

	gluLookAt( 0, 0, 2.5, 0, 0, -1, 0, 1, 0 );
}

